package com.hedl.practice.diyJava.multithreading.threadLocal.practise;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Client {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService es = Executors.newFixedThreadPool(3);
        String[] users = new String[] { "Bob", "Alice", "Tim", "Mike", "Lily", "Jack", "Bush" };
        for (String user : users) {
            es.submit(new Task(user));
        }
        es.awaitTermination(3, TimeUnit.SECONDS);
        es.shutdown();
    }
}


class UserContext implements AutoCloseable{
    private static final ThreadLocal<String> userThreadLocal = new ThreadLocal<>();

    public UserContext(String name){
        userThreadLocal.set(name);      //放入本地线程
        //输出本地线程名字加传入的username，这里的username调用的getCurrentUser()
        System.out.printf("[%s] init user %s...\n",Thread.currentThread().getName(),UserContext.getCurrentUser());
    }

    /**
     * ThreadLocal类的set(),get()方法，内部继承了map集合；是用当前线程名去存取username
     * @return
     */
    public static String getCurrentUser(){      //调用这里
        return userThreadLocal.get();       //在本地线程中取出对应的username
    }

    @Override
    public void close() throws Exception {      //线程最后关闭释放自动调用这个方法
        System.out.printf("[%s] cleanup for user %s...\n",Thread.currentThread().getName(),UserContext.getCurrentUser());
        userThreadLocal.remove();       //删除此线程局部变量的当前线程值。
    }
}

class Task implements Runnable{
    final String username;

    public Task(String username) {      //第一步
        this.username = username;
    }


    @Override
    public void run() {
        try(UserContext ctx = new UserContext(this.username)){      //第二步，这里把本类的this.usernam，给到了UserContext
            new Task1().process();
            new Task2().process();
            new Task3().process();
        } catch (Exception e) {
        }
    }
}

class Task1 {
    public void process(){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        System.out.printf("[%s] check user %s...\n",Thread.currentThread().getName(),UserContext.getCurrentUser());
    }
}

class Task2 {
    public void process() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        System.out.printf("[%s] %s registered ok.\n", Thread.currentThread().getName(),UserContext.getCurrentUser());
    }
}

class Task3 {
    public void process() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
        }
        System.out.printf("[%s] work of %s has done.\n", Thread.currentThread().getName(),UserContext.getCurrentUser());
    }
}
